﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web.Security;
using Media.Core.Data;
using Media.Core.Entities;
using Media.Core.Helpers.Main;
using Media.Core.Models.Tv;
using TvdbLib;
using TvdbLib.Data;
using TvdbLib.Data.Banner;

namespace Media.Core.Logic
{
    public class TvShowEngine
    {
        Database _db;

        public TvShowEngine(Database db)
        {
            _db = db;
        }


        public List<TvDirectories> AllTvShows()
        {
            var dtTvList = Connections.GetDataTable("Tv_Get_TvShows");

            return (from DataRow drTvList in dtTvList.Rows
                    select new TvDirectories
                               {
                                   Id = Convert.ToInt32(drTvList["Id"].ToString()), 
                                   name = drTvList["title"].ToString(), 
                                   Episodes = Convert.ToInt32(drTvList["Episodes"].ToString()),
                                   Rating = drTvList["Rating"].ToString(), 
                                   BannerImage = drTvList["BannerImage"].ToString(),
                                   Status = drTvList["Status"].ToString()
                               }).ToList();
        }

        public List<TvDirectories> UserTvShows(string UserId)
        {
            var paramsList = new ArrayList
                                       {
                                           new SqlParameter("UserId", UserId)
                                       };
            var dtTvList = Connections.GetDataTable("TvShow_Get_YourShows", paramsList);

            return (from DataRow drTvList in dtTvList.Rows
                    select new TvDirectories
                               {
                                   Id = Convert.ToInt32(drTvList["Id"].ToString()), 
                                   name = drTvList["title"].ToString(), 
                                   Episodes = Convert.ToInt32(drTvList["Episodes"].ToString()), 
                                   Rating = drTvList["Rating"].ToString(), 
                                   BannerImage = drTvList["BannerImage"].ToString()
                               }).ToList();
        }

        public SeriesInfo TvShowDetails(int tvShowId)
        {
            var paramsList = new ArrayList { new SqlParameter("Id", tvShowId) }; // Used for TvSeries
            var paramsList2 = new ArrayList { new SqlParameter("TvId", tvShowId) }; // Used for TvSeasons

            var drTvSeries = Connections.GetDataRow("TvSeries_Get_TvSeriesInfo", paramsList);
            var dtTvSeasons = Connections.GetDataTable("TvShow_Get_SeasonList", paramsList2);

            var tvSeasons = new SeasonArray();
            var testStartDate = "";
            var testEndDate = "";
            foreach (DataRow season in dtTvSeasons.Rows)
            {
                //Checks if the start or end date is NULL and sets it to ""
                if (season["StartDate"].ToString() != string.Empty)
                    testStartDate = Convert.ToDateTime(season["StartDate"].ToString()).ToLongDateString();
                if (season["EndDate"].ToString() != string.Empty)
                    testEndDate = Convert.ToDateTime(season["EndDate"].ToString()).ToLongDateString();

                tvSeasons.Seasons.Add(new Season
                {
                    TvSeasonId = Convert.ToInt32(season["SeasonId"].ToString()),
                    SeasonNumber = Convert.ToInt32(season["Season"].ToString()),
                    isWatched = Convert.ToBoolean(season["isWatched"].ToString()),
                    StartDate = testStartDate,
                    EndDate = testEndDate
                });

                //Resets the test dates to ""
                testStartDate = "";
                testEndDate = "";
            }

            var tv = new SeriesInfo
            {
                Id = Convert.ToInt32(drTvSeries["Id"].ToString()),
                SeriesName = drTvSeries["Title"].ToString(),
                Episodes = Convert.ToInt32(drTvSeries["Episodes"].ToString()),
                Rating = (float)Convert.ToDecimal(drTvSeries["Rating"].ToString()),
                Seasons = Convert.ToInt32(drTvSeries["Seasons"].ToString()),
                Status = drTvSeries["Status"].ToString(),
                BannerImage = drTvSeries["BannerImage"].ToString(),
                Description = drTvSeries["Description"].ToString(),
                ReleaseDate = drTvSeries["ReleaseDate"].ToString().Replace(" 12:00:00", ""), //Removes the 12:00:00 that gets stored in the DB.
                SeasonsList = tvSeasons.Seasons
            };
            return tv;
        }

        public EpisodeArray SeasonDetails(int tvId, int seasonId)
        {
            var seasonDetails = new ArrayList
            {
                new SqlParameter("TvId", tvId),
                new SqlParameter("SeasonId", seasonId)
            };
            var seasonDetails2 = new ArrayList
            {
                new SqlParameter("TvId", tvId),
                new SqlParameter("SeasonId", seasonId)
            };


            var dtEpisodes = Connections.GetDataTable("TvShow_Get_EpisodeBySeason", seasonDetails);
            var drShowTitle = Connections.GetDataRow("TvShow_Get_ShowAndSeason", seasonDetails2);
            var Episode = new EpisodeArray();

            Episode.ShowTitle = drShowTitle["Title"].ToString();
            Episode.Season = Convert.ToInt32(drShowTitle["Season"].ToString());

            foreach (DataRow episode in dtEpisodes.Rows)
            {
                Episode.Episodes.Add(new Episode
                {
                    Id = Convert.ToInt32(episode["SeasonId"].ToString()),
                    EpisodeNumber = Convert.ToInt32(episode["EpisodeNumber"].ToString()),
                    Title = episode["Title"].ToString(),
                    Rating = Convert.ToDecimal(episode["Rating"].ToString()),
                    AirDate = episode["AirDate"].ToString().Replace(" 12:00:00 AM", "")
                });
            }
            return Episode;
        }

        public List<LatestShow> GetComingEpisodes(int ListAmount = 20)
        {

            var eps = _db.Linq.Where<TvShow_Episode>(t => t.AirDate >= DateTime.Today.AddDays(-2)).OrderBy(s => s.AirDate).Select(LatestEps => new LatestShow
                {
                    EpisodeId = (int)LatestEps.EpisodeId,
                    ShowName = LatestEps.Tv.Title,
                    Episode = (int)LatestEps.EpisodeId,
                    Season = Convert.ToInt32(LatestEps.TvShow_Season.Season),
                    EpisodeName = LatestEps.Title,
                    //Adding one day because of australian time. 
                    //TODO : Implement a way for the user to select time zone
                    AirDate = Convert.ToDateTime(LatestEps.AirDate).AddDays(1).ToString().Replace(" 12:00:00 AM", "")
                }).Take(ListAmount).ToList();

            return (eps);
            
        }

        public int CheckExists(string SeriesName)
        {
            try
            {
                var GotTvShow = _db.Linq.Single<Tv>(t => t.Title == SeriesName).Title;
                return 0;
            }
            catch
            {
                return 1;
            }
        }

        public string AddFileLocations(string tvShow, string username, string type, string location)
        {
            var paramsList = new ArrayList
            {
                new SqlParameter("TvShow", tvShow),
                new SqlParameter("User", username),
                new SqlParameter("Type", type),
                new SqlParameter("Location", location)
            };
            Connections.GetDataRow("TvShow_Insert_UserLocation", paramsList);

            return "success";
        }

        public string Search(System.IO.DirectoryInfo[] dirInfos, string username)
        {
            try
            {
                var tvHandler = new TvdbHandler("73321F601FA4C423"); // API key for tvdb.com. User -> robrulez16 -> pass -> XXXX

                foreach (System.IO.DirectoryInfo d in dirInfos)
                {
                    //Tv Show Data
                    var series = tvHandler.SearchSeries(d.Name); // Searches for the tv Show. Gets first show found. Maybe implement a selection if needed...

                    var gotTv = CheckExists(series[0].SeriesName);

                    if (gotTv == 1)
                    {
                        //Tv Show Data

                        TvdbSeries s = tvHandler.GetSeries(series[0].Id, TvdbLanguage.DefaultLanguage, true, false, true, false);

                        //var tvBannerSave = ImageGrabber.GetAndSave(GetDirectory.Location("Tv Banner Site") + s.BannerPath, s.SeriesName, s.SeriesName + " SeriesBanner", "Tv Banner");

                        var tvShowList = new ArrayList
                        {
                            new SqlParameter("ShowName", s.SeriesName),
                            new SqlParameter("Episodes", s.Episodes.Count),
                            new SqlParameter("Rating", s.Rating),
                            new SqlParameter("FirstAired", s.FirstAired),
                            new SqlParameter("Description", s.Overview),
                            new SqlParameter("BannerImage", "5"),
                            new SqlParameter("Status", s.Status)
                        };

                        var newTvShow = Connections.GetDataRow("TvShow_Insert_New", tvShowList);
                        var tvId = Convert.ToInt32(newTvShow["Id"].ToString());


                        // Seasons and Season Banners
                        foreach (TvdbSeasonBanner b in s.SeasonBanners)
                        {
                            //var tvSeasonBannerSave = ImageGrabber.GetAndSave(GetDirectory.Location("Tv Banner Site") + b.BannerPath, s.SeriesName, b.BannerPath, "Tv Season Banner");

                            var tvSeasonBanners = new ArrayList
                            {
                                new SqlParameter("SeriesName", s.SeriesName),
                                new SqlParameter("SeasonNumber", b.Season),
                                new SqlParameter("Image", "5"),
                                new SqlParameter("IsWatched", false)
                            };

                            Connections.GetDataRow("TvShow_Insert_Seasons", tvSeasonBanners);

                        }

                        //Tv Episode Data
                        foreach (TvdbEpisode e in s.Episodes)
                        {
                            var airdate = e.FirstAired.ToString();
                            airdate = (airdate == "1/01/0001 12:00:00 AM") ? " 1/1/1800 12:00:00 AM" : airdate;

                            var episodes = new ArrayList
                            {
                                new SqlParameter("TvId", tvId),
                                new SqlParameter("TvDbId", e.Id),
                                new SqlParameter("SeasonNumber", e.SeasonNumber),
                                new SqlParameter("EpisodeNumber", e.EpisodeNumber), 
                                new SqlParameter("Name", e.EpisodeName),
                                new SqlParameter("AirDate", Convert.ToDateTime(airdate)),
                                new SqlParameter("Overview", e.Overview), 
                                new SqlParameter("Rating", e.Rating)
                            };

                            Connections.GetDataRow("TvShow_Insert_Episodes", episodes);
                        }
                    }

                    //Inserts the TvShow Id to the User.
                    AddFileLocations(series[0].SeriesName, username, "TvShow", d.Name);
                }

                return "Added Successfully";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
    }
}
